package com.payroll.framework;

import org.apache.log4j.*;
import org.apache.struts.action.*;

/*******************************************************
 *                                                     *
 *
 *                                                     *
 *******************************************************
*/
/**
 * General exception that handles all Payroll exceptions.
 * @author: Administrator
 */
public class PayrollFoundationException extends PayrollException {
	protected int i_ErrorCode;
	protected java.lang.String i_ClassAndMethodName;
	protected java.lang.String[] i_Substitutions;
	protected ActionErrors errors;


public PayrollFoundationException() {
	super();
	setI_ClassAndMethodName(getLocation(true));
	i_ErrorCode = 0;
	i_Substitutions = new String[] {new String(getLocation(false))};
}

public PayrollFoundationException(Throwable cause){
	super(cause);
	setI_ClassAndMethodName(getLocation(true));
	i_ErrorCode = 0;
	i_Substitutions = new String[] {new String(getLocation(false))};
}

public PayrollFoundationException(String message, Throwable cause){
	super(message,cause);
	setI_ClassAndMethodName(getLocation(true));
	i_ErrorCode = 0;
	i_Substitutions = new String[] {new String(getLocation(false))};
}

/**
 * Create PayrollFoundationException with a database-defined error message.
 * @param p_ClassAndMethodName The class and location this error is being thrown from. (Class.method)
 * @param p_ErrorCode The error code as defined in the EXC_MESSAGE table or AMSErrorConstants.
 * @author S Popovic
 */
public PayrollFoundationException(String p_ClassMethod, int p_ErrorCode) {
	setI_ClassAndMethodName(p_ClassMethod);
	i_ErrorCode  = p_ErrorCode;
	i_Substitutions = new String[] {new String("")};
	addError(p_ErrorCode);
}
/**
 * Create PayrollFoundationException with a database-defined error message and substitutions.
 * @param p_ClassAndMethodName The class and location this error is being thrown from. (Class.method)
 * @param p_ErrorCode The error code as defined in the EXC_MESSAGE table or AMSErrorConstants.
 * @param p_Substitutions An array of substitutions to be spliced into the error message.
 * @author S Popovic
 */
public PayrollFoundationException(String p_ClassAndMethodName, int p_ErrorCode,String[] p_Substitutions) {
	setI_ClassAndMethodName(p_ClassAndMethodName);
	i_ErrorCode = p_ErrorCode;
	i_Substitutions = p_Substitutions;

	addError(p_ErrorCode, p_Substitutions);
}
/**
 * Create PayrollFoundationException with a database-defined error message and 1 substitution. Serves as a convenience
 * method so developers needn't create an array with 1 element.
 * @param p_ClassAndMethodName The class and location this error is being thrown from. (Class.method)
 * @param p_ErrorCode The error code as defined in the EXC_MESSAGE table or AMSErrorConstants.
 * @param p_Substitutions An array of substitutions to be spliced into the error message.
 * @author S Popovic
 */
public PayrollFoundationException(String p_ClassAndMethodName, int p_ErrorCode,String p_Substitution) {
	setI_ClassAndMethodName(p_ClassAndMethodName);
	i_ErrorCode = p_ErrorCode;
	i_Substitutions = new String[] {p_Substitution};

	addError(p_ErrorCode, p_Substitution);
}

/**
 * Create an PayrollFoundationException exception with a non-database defined error message.  This constructor should only be used
 * for framework related errors when there might be the possibility of no database connection thus no error hash map.
 * @param p_ClassAndMethodName The class name and method throwing this error.
 * @param p_ErrorMessage The developer defined error message.
 * @author S Popovic
 */
public PayrollFoundationException(String p_ClassAndMethodName, String p_ErrorMessage) {
	super(p_ErrorMessage);
	i_ClassAndMethodName = p_ClassAndMethodName;

	addError(p_ErrorMessage);
}

private void addError(int p_ErrCode)
{
	getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError(String.valueOf(p_ErrCode)));
}

private void addError(int p_ErrCode, String p_Replace)
{
	getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError(String.valueOf(p_ErrCode), p_Replace));
}

private void addError(int p_ErrCode, String[] p_ReplaceArray)
{
	// Establish error logging category
    Category m_category =
        Category.getInstance(this.getClass().getName() + ".perform");

	String errCode = String.valueOf(p_ErrCode);

	switch(p_ReplaceArray.length)
	{
		case 1:
			getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError(errCode, p_ReplaceArray[0]));
			break;

		case 2:
			getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError(errCode, p_ReplaceArray[0], p_ReplaceArray[1]));
			break;

		case 3:
			getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError(errCode, p_ReplaceArray[0], p_ReplaceArray[1],
				p_ReplaceArray[2]));
			break;

		case 4:
			getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError(errCode, p_ReplaceArray[0], p_ReplaceArray[1],
				p_ReplaceArray[2], p_ReplaceArray[3]));
			break;

		default:
			m_category.warn("Too many substitution strings for Struts ActionError class!");
			getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError(errCode, p_ReplaceArray[0], p_ReplaceArray[1],
				p_ReplaceArray[2], p_ReplaceArray[3]));
			break;

	}
}

private void addError(String p_ErrorMessage)
{
	getErrors().add(ActionErrors.GLOBAL_ERROR, new ActionError("999", p_ErrorMessage));
}


/**
 * Returns the class and method name that represents where this error was thrown.
 * @return A string representing the class and method name where this error was thrown.
 * @author S Popovic
 */
public java.lang.String getI_ClassAndMethodName() {
	return i_ClassAndMethodName;
}
/**
 * Returns the Error Code for this exception.
 * @return The exception error code.
 * @author S Popovic
 */
public int getI_ErrorCode() {
	return i_ErrorCode;
}

/**
 * Returns the substitution values for this exception.
 * @return The exception substitution values.
 * @author S Popovic
 */
public java.lang.String[] getI_Substitutions() {
	return i_Substitutions;
}
/**
 * Sets the class and method name for this exception.
 * @param p_I_ClassAndMethodName A string representing the class and method name.
 * @author S Popovic
 */
public void setI_ClassAndMethodName(java.lang.String p_I_ClassAndMethodName) {
	i_ClassAndMethodName = p_I_ClassAndMethodName;
}
/**
 * Sets the substitution values for this exception.
 * @param p_Substitutions The substitution values for this exception.
 * @author S Popovic
 */
public void setI_Substitutions(java.lang.String[] p_Substitutions) {
	i_Substitutions = p_Substitutions;
}

	/**
	 * Gets the errors
	 * @return Returns a ActionErrors
	 */
	public ActionErrors getErrors() {
		if(errors == null)
		{
			errors = new ActionErrors();
		}

		return errors;
	}

	/**
	 * Sets the errors
	 * @param errors The errors to set
	 */
	public void setErrors(ActionErrors errors) {
		this.errors = errors;
	}

	public String getLocation(boolean p_pathOnly) {
        Throwable t = new Throwable();
        StackTraceElement[] m_stack      = t.getStackTrace();
        String              m_className  = "";
        String              m_fileName  = "";
        String              m_methodName = "";
        int              	m_lineNo;
        String 				m_location	 = "";
        for (int i = 2; i < m_stack.length; i++) {
            StackTraceElement m_ele = m_stack[ i ];
            m_fileName  = m_ele.getFileName();
            m_className = m_ele.getClassName();
            m_methodName = m_ele.getMethodName();
            m_lineNo = m_ele.getLineNumber();
            m_location = m_location+m_className+"::"+m_methodName+"() @ :"+m_lineNo+"\n";
            if (p_pathOnly)
            	break;
         }
		return m_location;
	}
}
